﻿using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using JT808.Protocol;

namespace JT808.Gateway.Abstractions
{
    /// <summary>
    /// 网关webapi服务工具
    /// </summary>
    public interface IJT808WebApiService
    {
        /// <summary>
        /// 为请求分配的消息订阅id及其状态
        /// id生成方式为终端号码+请求消息id+请求消息流水号
        /// 状态：0-已发送 1-已响应 2-超时
        /// </summary>
        public ConcurrentDictionary<string, byte> SubscribeIds { get; set; }
        /// <summary>
        /// 回调信息（可选）
        /// </summary>
        public ConcurrentDictionary<string, CallbackContext> Callbacks { get; set; }
        /// <summary>
        /// （测试用）消息队列消费者会将最新的消息解析后缓存到这里供webapi调用
        /// </summary>
        public ConcurrentDictionary<string, byte[]> CachedResponse { get; set; }
        /// <summary>
        /// 收到回复时，将响应写入消息中间件
        /// </summary>
        public IJT808ApiResponseProducer Producer { get; set; }
        /// <summary>
        /// 尝试向设备发送消息，如果设备不在线，则返回false
        /// </summary>
        /// <param name="package">要发送的808报文</param>
        /// <param name="id">如果消息能订阅，则返回消息id，否则为空字符串</param>
        /// <param name="callback"></param>
        /// <returns>设备是否在线</returns>
        public Task<(bool success, string subscribeId)> TrySendIfOnline(JT808Package package, string callback = null);
        /// <summary>
        /// 尝试将设备回复写入消息中间件或回调回复
        /// </summary>
        /// <param name="headerPakcage"></param>
        /// <returns>如消息未订阅或超时，则返回false</returns>
        public bool TryResponseIfSubscribe(JT808HeaderPackage headerPakcage);
    }

    /// <summary>
    /// 回调上下文记录
    /// </summary>
    public class CallbackContext
    {
        /// <summary>
        /// 回调地址
        /// </summary>
        public Uri CallbackUrl { get; set; }
        /// <summary>
        /// 过期时间
        /// </summary>
        public DateTimeOffset ExpireTime { get; set; }
    }
}
